"""Normalize Affy Data

.. helpdoc::
This widget performs normalization of affy data.  This widget will only take signals of the RAffyBatch signal class.  

Normalization may be performed using either the RMA, MAS5, or a custom configuration.  By default the custom configuration is a close approximation of normalization proposed by Li and Wong (as used in the dChip program).

This widget sends a normalized eSet signal.  These signals can be converted to matrix signal types, with the loss of associated phenotypic data, though users can extract all levels using other tools.
"""

"""<widgetXML>
<name>Normalize Affy Data</name>
    <icon>default.png</icon>
    <tags>
        <tag>Affy</tag>
    </tags>
    <summary>This widget normalizes gene expression data contained in an affy dataset.</summary>
    <details>This widget normalizes gene expression data contained in an affy dataset.</details>
    <author>
        <authorname>Kyle R Covington</authorname>
        <authorcontact>kyle@red-r.org</authorcontact>
    </author>
</widgetXML>
"""


"""
<name>Normalize</name>
<description>Processes an Affybatch to an eset using RMA</description>
<tags>Array Analysis</tags>
"""


from OWRpy import *
# import OWGUI
import signals
import redRGUI, globalData
import libraries.affy.signalClasses.RAffyBatch as rab
import libraries.affy.signalClasses.REset as reset
from libraries.base.qtWidgets.groupBox import groupBox as redRGroupBox
from libraries.base.qtWidgets.radioButtons import radioButtons as redRRadioButtons
from libraries.base.qtWidgets.button import button as redRButton
from libraries.base.qtWidgets.commitButton import commitButton as redRCommitButton
from libraries.base.qtWidgets.comboBox import comboBox as redRComboBox
class affyNormalize(OWRpy):
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        
        self.normmeth = 'quantiles'
        self.normoptions = ''
        self.norm = ['quantiles']
        self.data = ''
        self.enableMethBox = False
        self.norminfo = ''
        self.require_librarys(['affy'])
        
        #set R variable names
        self.setRvariableNames(['normalized_Eset'])
        
        #signals
        
        """.. rrsignals::"""
        self.inputs.addInput('ab', "AffyBatch", rab.RAffyBatch, self.process)
        
        """.. rrsignals::"""
        self.outputs.addOutput('ne', "Normalized Eset", reset.REset)

        
        #the GUI
        
        """.. rrgui::"""
        self.selMethBox = redRRadioButtons(self.controlArea, label='Normalization Method',
        buttons=["RMA", "MAS5", "Custom"], 
        callback=self.selectMethodChanged,orientation='horizontal')
        self.selMethBox.setChecked('RMA')
        
        info = redRGroupBox(self.controlArea, label = "Normalization Options")

        
        #insert a block to check what type of object is connected.  If nothing connected set the items of the normalize methods objects to 
        
        """.. rrgui::"""
        self.normselector = redRComboBox(info, label="Normalization Method", items=self.norm, orientation=0)
        self.normselector.setEnabled(False)
        
        """.. rrgui::"""
        self.bgcorrectselector = redRComboBox(info, label="Background Correct Methods", items=['TRUE', 'FALSE'], orientation=0)
        self.bgcorrectselector.setEnabled(False)
        
        """.. rrgui::"""
        self.bgcmethselector = redRComboBox(info, label="Background Correct Methods", items=[],
        #self.R('bgcorrect.methods'), 
        orientation=0)
        self.bgcmethselector.setEnabled(False)
        
        """.. rrgui::"""
        self.pmcorrectselector = redRComboBox(info, label="Perfect Match Correct Methods",
        items=[]
        #self.R('pmcorrect.methods')
        , orientation=0)
        self.pmcorrectselector.setEnabled(False)
        
        """.. rrgui::"""
        self.summethselector = redRComboBox(info, label="Summary Methods", items=[]
        #self.R('express.summary.stat.methods')
        , orientation=0)
        self.summethselector.setEnabled(False)
        
        
        runbutton = redRButton(self.bottomAreaRight, label = "Run Normalization", callback = self.normalize)
        # runbutton.layout().setAlignment(Qt.AlignRight)
        
    def normalize(self):
        if self.data == '': return
        self.status.setText('Processing')
        if self.selMethBox.getChecked() == 'RMA':
            self.R(self.Rvariables['normalized_Eset']+'<-rma('+self.data+')', wantType = 'NoConversion') #makes the rma normalization
            self.norminfo = 'Normalized with RMA'
        if self.selMethBox.getChecked() == 'MAS5':
            self.R(self.Rvariables['normalized_Eset']+'<-mas5('+self.data+')', wantType = 'NoConversion') #makes the mas5 normalization
            self.norminfo = 'Normalized with MAS5'
        if self.selMethBox.getChecked() == 'Custom':
            self.R(self.Rvariables['normalized_Eset']+'<-expresso('+self.data+', bg.correct='+self.bgcorrectselector.currentText()+', bgcorrect.method="'+self.bgcmethselector.currentText()+'", pmcorrect.method="'+self.pmcorrectselector.currentText()+'", summary.method="'+self.summethselector.currentText()+'")', wantType = 'NoConversion')
            self.norminfo = 'Normalized by: Background Correction:'+self.bgcorrectselector.currentText()+', Method:'+self.bgcmethselector.currentText()+', Perfect Match Correct Method: '+self.pmcorrectselector.currentText()+', Summary Method: '+self.summethselector.currentText()
        self.toSend()
        self.status.setText(self.norminfo)
        
    # def collectOptions(self):
        # if self.normselector.currentText() == None: self.normoptions = ""
        # elif self.normselector.currentText() == "":
            ##self.normselector.setText("")
            # self.collectOptions()
        # else:
            # self.normoptions = ',method='+self.normselector.currentText()
    
    def process(self, dataset):     
        try: 
            print dataset
            self.data = unicode(dataset.getData())
            
            if self.R('length(exprs('+self.data+')[1,])', wantType = 'convert') > 10:
                self.selectMethod = 2
                self.selectMethodChanged()
                
            else:
                self.selectMethod = 0
                self.selectMethodChanged()
                
            self.selMethBox.setEnabled(True)
            self.status.setText('Data Loaded')
        except: 
            print '|###| error'

        
        self.bgcmethselector.update(self.R('bgcorrect.methods()', wantType = 'list'))
        self.pmcorrectselector.update(self.R('pmcorrect.methods()', wantType = 'list'))
        self.summethselector.update(self.R('express.summary.stat.methods()', wantType = 'list'))
        
    
    def selectMethodChanged(self):

        if self.selMethBox.getChecked() == 'RMA':
            self.bgcorrectselector.setEnabled(False)
            self.bgcmethselector.setEnabled(False)
            self.pmcorrectselector.setEnabled(False)
            self.summethselector.setEnabled(False)
            self.normselector.setEnabled(False)
        elif self.selMethBox.getChecked() == 'MAS5':
            self.bgcorrectselector.setEnabled(False)
            self.bgcmethselector.setEnabled(False)
            self.pmcorrectselector.setEnabled(False)
            self.summethselector.setEnabled(False)
            self.normselector.setEnabled(False)
        elif self.selMethBox.getChecked() == 'Custom':
            self.bgcorrectselector.setCurrentIndex(self.bgcorrectselector.findText('FALSE'))
            self.bgcorrectselector.setEnabled(True)
            self.bgcorrectmeth = 'none'
            self.bgcmethselector.setCurrentIndex(self.bgcmethselector.findText('none'))
            self.bgcmethselector.setEnabled(True)
            self.pmcorrect = 'pmonly'
            self.pmcorrectselector.setCurrentIndex(self.pmcorrectselector.findText('pmonly'))
            self.pmcorrectselector.setEnabled(True)
            self.summarymeth = 'liwong'
            self.summethselector.setCurrentIndex(self.summethselector.findText('liwong'))
            self.summethselector.setEnabled(True)
            self.norm = ['quantiles']
            self.normselector.clear()
            if self.data != '': # normalize.methods() results in an error in R
                self.normselector.addItems(self.R('normalize.methods('+self.data+')', wantType = 'list'))
                self.normselector.setCurrentIndex(self.normselector.findText('invariantset'))
                self.normselector.setEnabled(True)

    def toSend(self):
        globalData.setGlobalData(self,'eset',self.Rvariables['normalized_Eset'],description='Normalized Eset')
        
        newData = reset.REset(self, data = self.Rvariables['normalized_Eset'])
        self.rSend("ne", newData)
        
    
